#include <iostream>
#include <unistd.h>
#include <cstring>
#include "Log.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "InetAddr.hpp"
#include <pthread.h>
#include "openterminal.hpp"

// 客户端不需要也不能显式绑定IP与port，由OS来做
// 客户端需要输入服务器的主机号与端口号

struct SocketData
{
    std::string serverip;
    uint16_t serverport;
    struct sockaddr_in server;
    int sockfd;
};

void Usage(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << "severip severport!\n"
              << std::endl;
}

// 接收消息
void *recvmsg(void *args)
{
    SocketData *sd = static_cast<SocketData *>(args);
    while (true)
    {
        socklen_t len = sizeof(sd->server);
        // 接收
        std::string message;
        char buffer[1024];
        ssize_t n = recvfrom(sd->sockfd, buffer, sizeof(buffer) - 1, 0, (sockaddr *)&sd->server, &len);
        if (n > 0)
        {
            buffer[n] = 0;
            std::cerr << buffer << std::endl;
        }
    }
}
void *sendmsg(void *args)
{
    SocketData *sd = static_cast<SocketData *>(args);
    std::string welcome = sd->serverip + "comming!";
    socklen_t len = sizeof(sd->server);    
    sendto(sd->sockfd, welcome.c_str(), welcome.size(), 0, (sockaddr *)&sd->server, len);
    std::string message;
    while (true)
    {
        std::cout << "Enter your message# ";
        std::getline(std::cin, message);
        // 发送
        sendto(sd->sockfd, message.c_str(), message.size(), 0, (sockaddr *)&sd->server, len);
    }
}
int main(int argc, char *argv[])
{
    // 打开另一终端的显示器，用于接收聊天室消息
    // if (!OpenTerminal())
    // {
    //     Log(DEBUG, "revemsg terminal open false...[%d,%s]", errno, strerror(errno));
    //     exit(3);
    // }
    Log(DEBUG, "revemsg terminal open success...");
    // std::cout<<"hahaha"<<std::endl;
    if (argc != 3)
    {
        Usage(argv[0]);
        return -1;
    }
    // 创建套接字描述符
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // ipv4,udp
    if (sockfd < 0)                              // 获取失败
    {
        Log(FATAL, "client sockfd get fail,[%s,%d]", strerror(errno), errno);
        exit(-1);
    }
    Log(DEBUG, "client sockfd get success...");

    std::string IP = argv[1];
    uint16_t port = std::stoi(argv[2]);

    // 获取网络字节序并存入套接字结构体
    struct sockaddr_in sever;
    sever.sin_addr.s_addr = inet_addr(IP.c_str());
    sever.sin_port = htons(port);
    sever.sin_family = AF_INET;

    Log(DEBUG, "UdpClient already start success...");
    SocketData sd;
    sd.server = sever;
    sd.serverip = IP;
    sd.serverport = port;
    sd.sockfd = sockfd;
    // 创建接收与发送线程
    pthread_t recvtid, sendtid;
    pthread_create(&recvtid, nullptr, recvmsg, &sd);
    pthread_create(&sendtid, nullptr, sendmsg, &sd);

    pthread_join(recvtid, nullptr);
    pthread_join(sendtid, nullptr);
    close(sockfd);
    return 0;
}
